#ifndef _IIIMP_AUX_H
#define _IIIMP_AUX_H


#include <X11/Xmd.h>
#include <X11/Xlib.h>

typedef struct _aux_service	aux_service_t;
typedef struct _aux_im_data	aux_im_data_t;

typedef struct _XicCommon *XicCommon;

typedef struct _aux {
	XicCommon		ic;		/* input context */
	aux_service_t *		service;	/* Aux service method */
	aux_im_data_t *		im;		/* current IM */
	aux_im_data_t *		im_list;	/* list of IM structure */
} aux_t;


typedef enum {
	AUX_DATA_NONE = 0,
	AUX_DATA_START = 1,
	AUX_DATA_DRAW = 2,
	AUX_DATA_DONE = 3,
	AUX_DATA_SETVALUE = 4,
	AUX_DATA_GETVALUE = 5,
	AUX_DATA_GETVALUE_REPLY = 6,
} aux_data_type_t;


typedef struct {
	int		length;
	unsigned char *	ptr;
} aux_string_t;


typedef struct {
	aux_data_type_t	type;
	int		im;
	int		ic;
	int		aux_index;
	int		aux_name_length;
	unsigned char *	aux_name;
	int		integer_count;
	int *		integer_list;
	int		string_count;
	aux_string_t *	string_list;
	unsigned char *	string_ptr;
} aux_data_t;


struct _aux_service {
	void		(* aux_setvalue)(aux_t *, const unsigned char *, int);
	int		(* im_id)(aux_t *);
	int		(* ic_id)(aux_t *);
	void		(* data_set)(aux_t *, int, void *);
	void *		(* data_get)(aux_t *, int);
	Display *	(* display)(aux_t *);
	Window		(* window)(aux_t *);
	XPoint *	(* point)(aux_t *, XPoint *);
	XPoint *	(* point_caret)(aux_t *, XPoint *);
	size_t		(* utf16_mb)(const char **, size_t *,
				     char **, size_t *);
	size_t		(* mb_utf16)(const char **, size_t *,
				     char **, size_t *);
	unsigned char *	(* compose)(const aux_data_t *, int *);
	int		(* compose_size)(aux_data_type_t,
					 const unsigned char *);
	aux_data_t *	(* decompose)(aux_data_type_t, const unsigned char *);
	void		(* decompose_free)(aux_data_t *);
	void		(* register_X_filter)(Display *, Window, int, int, 
					      Bool (* filter)(Display *,
							      Window,
							      XEvent *,
							      XPointer),
					      XPointer);
	void		(* unregister_X_filter)(Display *, Window,
						Bool (* filter)(Display *,
								Window,
								XEvent *,
								XPointer),
						XPointer);
	Bool		(* server)(aux_t *);
	Window		(* client_window)(aux_t *);
	Window		(* focus_window)(aux_t *);
	int		(* screen_number)(aux_t *);
	int		(* point_screen)(aux_t *, XPoint *);
	int		(* point_caret_screen)(aux_t *, XPoint *);
	Bool		(* get_conversion_mode)(aux_t *);
	void		(* set_conversion_mode)(aux_t *, int);
		/* if_version(1st arg of register_service()) >= AUX_IF_VERSION_2 */
	void		(* aux_getvalue)(aux_t *, const unsigned char *, int);
	aux_t *		(* aux_get_from_id)(int im_id, int ic_id,
						CARD16 *aux_name, int aux_name_length);
};


typedef struct _aux_method {
	Bool	(* create)(aux_t *);
	Bool	(* start)(aux_t *, const unsigned char *, int);
	Bool	(* draw)(aux_t *, const unsigned char *, int);
	Bool	(* done)(aux_t *, const unsigned char *, int);
	Bool	(* switched)(aux_t *, int, int);
	Bool	(* destroy)(aux_t *);
		/* aux_info_t.if_version >= AUX_IF_VERSION_2 */
	Bool	(* getvalues_reply)(aux_t *, const unsigned char *, int);
	Bool	(* destroy_ic)(aux_t *);
	Bool	(* set_icforcus)(aux_t *);
	Bool	(* unset_icforcus)(aux_t *);
} aux_method_t;


typedef struct {
	int		len;
	CARD16 *	ptr;
} aux_name_t;


typedef struct {
	aux_name_t	name;
	aux_method_t *	method;
} aux_dir_t;


typedef struct {
	unsigned int	if_version;		/* >= AUX_IF_VERSION_2 */
	Bool		(* register_service)(unsigned int  if_version,
					   aux_service_t *service);
	aux_dir_t	*dir;
} aux_info_t;
#define	AUX_IF_VERSION_2	0x00020000

#endif /* !_IIIMP_AUX_H */
